package com.fang.dubbo.mock.rpc.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import lombok.extern.slf4j.Slf4j;

/**
 * @author fanglingxiao
 * @version 1.0
 * @description TODO
 * @date 2022/1/2 12:24 下午
 **/
@Slf4j
public class NettyServer {

    /**
     * 对外暴露方法
     *
     * @author fanglingxiao
     * @createDateTime 2022/1/2 1:08 下午
     */
    public static void startServer(String hostname, int port) {
        startServer0(hostname, port);
    }

    /**
     * 对nettyServer的舒适化和启动
     *
     * @param hostname 主机名
     * @param port     端口号
     * @author fanglingxiao
     * @createDateTime 2022/1/2 12:25 下午
     */
    private static void startServer0(String hostname, int port) {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup(8);

        try {
            ServerBootstrap bootstrap = createServerBootstrap(bossGroup, workerGroup);
            ChannelFuture channelFuture = bootstrap.bind(hostname, port).sync();
            log.info("NettyServer 服务提供方开始提供服务");
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private static ServerBootstrap createServerBootstrap(EventLoopGroup bossGroup, EventLoopGroup workerGroup) {
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    //                        private MessageLite lite = null;
                    @Override
                    protected void initChannel(SocketChannel sc) throws Exception {
                        ChannelPipeline pipeline = sc.pipeline();
                        /*
                         * 解码/编码
                         * protobuf
                         * 添加ProtobufVarint32FrameDecoder以分隔帧
                         * 添加ProtobufEncoder以处理消息的编码
                         * 添加ProtobufDecoder以解码消息
                         */
                        /*pipeline.addLast(new ProtobufVarint32FrameDecoder());
                        pipeline.addLast(new ProtobufEncoder());
                        pipeline.addLast(new ProtobufDecoder(lite));*/
                        pipeline.addLast(new ObjectDecoder(1024 * 1024,
                                ClassResolvers.cacheDisabled(this.getClass().getClassLoader())));
                        pipeline.addLast(new ObjectEncoder());
                        // 业务处理器
                        pipeline.addLast(new NettyServerHandler());
                    }
                });
        return bootstrap;
    }
}
